#include "tasktest.h"
#include <cstdio>
/*Registry this TestSuite to theTestFactoryRegistry*/
CPPUNIT_TEST_SUITE_REGISTRATION (TaskTest);

void TaskTest::setUp() {
	SG_init();
	task = new Task("task_1", 100, 1, 5000, 0);
}

void TaskTest::testGetNumberOfReplicas() { fprintf(stderr,">>> TaskTest::testGetNumberOfReplicas()\n");
	CPPUNIT_ASSERT_MESSAGE("Number of tasks shoud be 0!",task->getNumberOfReplicas() == 0);
}
		

void TaskTest::testGetName() { fprintf(stderr,">>> TaskTest::testGetName()\n");
	CPPUNIT_ASSERT_MESSAGE("Task name should be \"task_1\"" ,(!strcmp(task->getName(), "task_1")));
}

void TaskTest::testGetDataInputOutput() { fprintf(stderr,">>> TaskTest::testGetDataInputOutput()\n");
	DataElement *input = task->getDataInput();
	DataElement *output = task->getDataOutput();
	char *inputName = new char[64];
	char *outputName= new char[64];
	
	sprintf(inputName, "input_%s", task->getName());
	sprintf(outputName, "output_%s", task->getName());	

	CPPUNIT_ASSERT_MESSAGE("Data Input name should be input_taskname" ,(!strcmp(inputName, input->getName())));	
	CPPUNIT_ASSERT_MESSAGE("Data Output name should be output_taskname" ,(!strcmp(outputName, output->getName())));	

	CPPUNIT_ASSERT_EQUAL_MESSAGE("Data Input type should INPUT_DATA=1" , input->getType(), 0);		
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Data Input type should OUTPUT_DATA=1" ,output->getType(), 1);			

	CPPUNIT_ASSERT_MESSAGE("Data Input size should be 5000" ,input->getSize()==5000);				
	CPPUNIT_ASSERT_MESSAGE("Data Output size should be 0" ,output->getSize()==0);					
}

void TaskTest::testReplicate() { fprintf(stderr,">>> TaskTest::testReplicate()\n");
	task->replicate(5000);
	task->replicate(5000);
	task->replicate(0);	
	task->replicate(0);	
	task->replicate(0);		
	task->replicate(0);	
	CPPUNIT_ASSERT_MESSAGE("Number of replicas should be 6!",task->getNumberOfReplicas() == 6);	
	
	for (int n=0; n<task->getNumberOfReplicas(); n++) {
		char *taskReplicaName = new char[64];
		const char *comp_name = SG_getTaskName(task->getComputationReplicaByIndex(n));
		const char *transferIn_name = SG_getTaskName(task->getTransferReplicaByIndex(n, Task::IN));		
		const char *transferOut_name = SG_getTaskName(task->getTransferReplicaByIndex(n, Task::OUT));				
		sprintf(taskReplicaName, "%s_%d", task->getName(), (n+1));	
//		printf("task name=%s\n", task->getName());
//		printf("%s==%s==%s\n",taskReplicaName, comp_name, transfer_name);
		CPPUNIT_ASSERT_MESSAGE("Replica Name should be the taskname_n" ,(!strcmp(taskReplicaName, comp_name)));			
		CPPUNIT_ASSERT_MESSAGE("Replica Name should be the taskname_n" ,(!strcmp(taskReplicaName, transferIn_name)));					
		CPPUNIT_ASSERT_MESSAGE("Replica Name should be the taskname_n" ,(!strcmp(taskReplicaName, transferOut_name)));							
	}

	task->replicate(); //replica 6
	task->replicate(0); // replica 7
	CPPUNIT_ASSERT_MESSAGE("Cost of replica should be equal to task cost",task->getTransferCost(Task::IN)==SG_getTaskCost(task->getTransferReplicaByIndex(6, Task::IN)));	

	CPPUNIT_ASSERT_MESSAGE("Cost of replica should be 0",0==SG_getTaskCost(task->getTransferReplicaByIndex(7, Task::IN)));		

}

void TaskTest::testGetCost() { fprintf(stderr,">>> TaskTest::testGetCost()\n");
	CPPUNIT_ASSERT_MESSAGE("Computation Cost should be 50" , task->getComputationCost()==50);		
	CPPUNIT_ASSERT_MESSAGE("Transfer In Cost should be 5000" , task->getTransferCost(Task::IN)==5000);			
	CPPUNIT_ASSERT_MESSAGE("Transfer Out Cost should be 0" , task->getTransferCost(Task::OUT)==0);				
	
	
	task->modifyInputTransferCostTo(10);
	CPPUNIT_ASSERT_MESSAGE("Transfer In Cost should be modified to 10" , task->getTransferCost(Task::IN)==10);				
	task->restoreInputTransferCost();
	CPPUNIT_ASSERT_MESSAGE("Transfer In Cost should restored to 5000" , task->getTransferCost(Task::IN)==5000);				
}

void TaskTest::testClearReplicas() { fprintf(stderr,">>> TaskTest::testClearReplicas()\n");
	task->replicate(5000);
	task->replicate(5000);
	task->replicate(0);	
	task->replicate(0);	
	CPPUNIT_ASSERT_MESSAGE("Number of replicas should be 4!",task->getNumberOfReplicas() == 4);
	for (int n=0; n< task->getNumberOfReplicas(); n++) {
		CPPUNIT_ASSERT(task->getComputationReplicaByIndex(n)!=NULL);	
	}
	task->clearReplicas();
	CPPUNIT_ASSERT_MESSAGE("Number of replicas should be 0!",task->getNumberOfReplicas()==0);
	CPPUNIT_ASSERT(task->getComputationReplicas()==NULL);
	CPPUNIT_ASSERT(task->getTransferReplicas(Task::IN)==NULL);	
	CPPUNIT_ASSERT(task->getTransferReplicas(Task::OUT)==NULL);		

	task->replicate(0);	
	task->replicate(0);	
	CPPUNIT_ASSERT_MESSAGE("Number of replicas should be 2!",task->getNumberOfReplicas() == 2);
	
	
}

void TaskTest::testNotScheduled() { fprintf(stderr,">>> TaskTest::testNotScheduled()\n");
	CPPUNIT_ASSERT(task->notScheduled()==true);
	Processor *p = new Processor("proc_1", 2, 0.987);
	SG_scheduleTaskOnResource(task->getComputation(), p->getSGResource());
	CPPUNIT_ASSERT(task->notScheduled()==false);	
	
}

void TaskTest::tearDown() {
	delete task;
	SG_clear();
}
